package org.cybzacg.convert.converters.essential;


import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.core.AbstractTypeConverter;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;


/**
 * 字符串类型转换器
 * 专门处理字符串类型的转换
 *
 * @author cybzacg.blog
 * @version 3.0
 * @since 3.0
 */
@Slf4j
@Converter(
    name = "StringConverter",
    priority = ConversionPriority.ESSENTIAL,
    description = "字符串类型转换器，处理各种类型到字符串的转换",
    enabled = true,
    version = "3.1",
    author = "cybzacg.blog",
    supportedTypes = {String.class},
    tags = {"string", "basic", "conversion"}
)
public class StringConverter extends AbstractTypeConverter {

    public StringConverter() {
        super(ConversionPriority.ESSENTIAL);
        log.debug("初始化字符串转换器");
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.STRING;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> T doConvert(Object source, Class<T> targetType, T defaultValue, ConversionContext context)
            throws Exception {

        if (source == null) {
            return defaultValue;
        }

        // 如果已经是字符串类型，直接返回
        if (source instanceof String) {
            return (T) source;
        }

        // 转换为字符串
        String result = convertToString(source, context);

        return (T) result;
    }

    /**
     * 将对象转换为字符串
     *
     * @param source 源对象
     * @param context 转换上下文
     * @return 字符串结果
     */
    protected String convertToString(Object source, ConversionContext context) {
        if (source == null) {
            return context.getDefaultValue() != null ? context.getDefaultValue().toString() : "";
        }

        // 处理常见类型的转换
        if (source instanceof CharSequence) {
            return source.toString();
        }

        if (source instanceof Character) {
            return source.toString();
        }

        if (source instanceof Number) {
            return source.toString();
        }

        if (source instanceof Boolean) {
            return source.toString();
        }

        if (source instanceof java.util.Date) {
            return convertDateToString((java.util.Date) source, context);
        }

        if (source instanceof java.time.temporal.TemporalAccessor) {
            return convertTemporalToString((java.time.temporal.TemporalAccessor) source, context);
        }

        if (source.getClass().isArray()) {
            return convertArrayToString(source, context);
        }

        if (source instanceof java.util.Collection) {
            return convertCollectionToString((java.util.Collection<?>) source, context);
        }

        if (source instanceof java.util.Map) {
            return convertMapToString((java.util.Map<?, ?>) source, context);
        }

        // 默认使用toString方法
        return source.toString();
    }

    /**
     * 转换日期为字符串
     *
     * @param date 日期对象
     * @param context 转换上下文
     * @return 字符串
     */
    protected String convertDateToString(java.util.Date date, ConversionContext context) {
        String format = context.getProperty("dateFormat");
        if (format != null) {
            try {
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(format);
                return sdf.format(date);
            } catch (Exception e) {
                // 格式化失败，使用默认格式
            }
        }

        // 默认格式
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    /**
     * 转换时间对象为字符串
     *
     * @param temporal 时间对象
     * @param context 转换上下文
     * @return 字符串
     */
    protected String convertTemporalToString(java.time.temporal.TemporalAccessor temporal, ConversionContext context) {
        String format = context.getProperty("dateFormat");
        if (format != null) {
            try {
                java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern(format);
                return formatter.format(temporal);
            } catch (Exception e) {
                // 格式化失败，使用默认格式
            }
        }

        // 默认格式
        if (temporal instanceof java.time.LocalDateTime) {
            return java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(temporal);
        } else if (temporal instanceof java.time.LocalDate) {
            return java.time.format.DateTimeFormatter.ISO_LOCAL_DATE.format(temporal);
        } else if (temporal instanceof java.time.LocalTime) {
            return java.time.format.DateTimeFormatter.ISO_LOCAL_TIME.format(temporal);
        } else if (temporal instanceof java.time.ZonedDateTime) {
            return java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME.format(temporal);
        } else if (temporal instanceof java.time.Instant) {
            return java.time.format.DateTimeFormatter.ISO_INSTANT.format(temporal);
        }

        return temporal.toString();
    }

    /**
     * 转换数组为字符串
     *
     * @param array 数组对象
     * @param context 转换上下文
     * @return 字符串
     */
    protected String convertArrayToString(Object array, ConversionContext context) {
        String separator = context.getProperty("arraySeparator");
        if (separator == null) {
            separator = ",";
        }

        if (array instanceof Object[]) {
            Object[] objArray = (Object[]) array;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < objArray.length; i++) {
                if (i > 0) {
                    sb.append(separator);
                }
                sb.append(objArray[i] != null ? objArray[i].toString() : "null");
            }
            return sb.toString();
        } else if (array instanceof int[]) {
            int[] intArray = (int[]) array;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < intArray.length; i++) {
                if (i > 0) {
                    sb.append(separator);
                }
                sb.append(intArray[i]);
            }
            return sb.toString();
        } else if (array instanceof long[]) {
            long[] longArray = (long[]) array;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < longArray.length; i++) {
                if (i > 0) {
                    sb.append(separator);
                }
                sb.append(longArray[i]);
            }
            return sb.toString();
        } else if (array instanceof double[]) {
            double[] doubleArray = (double[]) array;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < doubleArray.length; i++) {
                if (i > 0) {
                    sb.append(separator);
                }
                sb.append(doubleArray[i]);
            }
            return sb.toString();
        } else if (array instanceof boolean[]) {
            boolean[] boolArray = (boolean[]) array;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < boolArray.length; i++) {
                if (i > 0) {
                    sb.append(separator);
                }
                sb.append(boolArray[i]);
            }
            return sb.toString();
        }

        return array.toString();
    }

    /**
     * 转换集合为字符串
     *
     * @param collection 集合对象
     * @param context 转换上下文
     * @return 字符串
     */
    protected String convertCollectionToString(java.util.Collection<?> collection, ConversionContext context) {
        String separator = context.getProperty("collectionSeparator");
        if (separator == null) {
            separator = ",";
        }

        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Object item : collection) {
            if (!first) {
                sb.append(separator);
            }
            sb.append(item != null ? item.toString() : "null");
            first = false;
        }

        return sb.toString();
    }

    /**
     * 转换Map为字符串
     *
     * @param map Map对象
     * @param context 转换上下文
     * @return 字符串
     */
    protected String convertMapToString(java.util.Map<?, ?> map, ConversionContext context) {
        String keyValueSeparator = context.getProperty("keyValueSeparator");
        if (keyValueSeparator == null) {
            keyValueSeparator = "=";
        }

        String entrySeparator = context.getProperty("entrySeparator");
        if (entrySeparator == null) {
            entrySeparator = ",";
        }

        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (java.util.Map.Entry<?, ?> entry : map.entrySet()) {
            if (!first) {
                sb.append(entrySeparator);
            }
            sb.append(entry.getKey() != null ? entry.getKey().toString() : "null")
              .append(keyValueSeparator)
              .append(entry.getValue() != null ? entry.getValue().toString() : "null");
            first = false;
        }

        return sb.toString();
    }

    @Override
    public boolean supports(Class<?> targetType) {
        return targetType == String.class;
    }

    @Override
    public Class<?> getSupportedType() {
        return String.class;
    }
}
